package com.dingreading.cloud.soms.service.impl;

import com.dingreading.cloud.common.util.EnumType;
import com.dingreading.cloud.common.util.NepUtil;
import com.dingreading.cloud.common.util.PageUtil;
import com.dingreading.cloud.soms.dto.CmOrderCountDto;
import com.dingreading.cloud.soms.dto.CmorderDto;
import com.dingreading.cloud.soms.entity.Cmorders;
import com.dingreading.cloud.soms.entity.table.CmordersTableDef;
import com.dingreading.cloud.soms.mapper.CmordersMapper;
import com.dingreading.cloud.soms.service.CmordersService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import static com.dingreading.cloud.soms.entity.table.MembersTableDef.members;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class CmordersServiceImpl extends BaseServiceImpl<CmordersMapper, Cmorders, CmordersTableDef> implements CmordersService {

    @Override
    protected CmordersTableDef getTable() {
        return CmordersTableDef.cmorders;
    }

    @Override
    public Page<CmorderDto> storePage(
            PageUtil pageUtil, String storeUid, String memberUid, String keyword, String orderType,
            String beginDate, String endDate, Integer status
    ) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(memberUid))
            condition.and(table.memberUid.eq(memberUid));
        if (StringUtils.isNotBlank(keyword))
            condition.and(table.contractCode.like(keyword)
                    .or(table.memberName.like(keyword))
                    .or(members.memberName.like(keyword))
                    .or(table.orderCode.like(keyword))
            );
        if (StringUtils.isNotBlank(orderType))
            condition.and(table.orderType.eq(orderType));
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate))
            condition.and(table.orderDate.between(beginDate, endDate));
        if (null != status)
            condition.and(table.status.eq(status));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.allColumns, members.memberName.as("newMemberName"))
                .from(table)
                .where(condition)
                .leftJoin(members).on(table.memberUid.eq(members.uid))
                .orderBy(table.orderDate.desc(), table.id.desc());
        return getMapper().paginateAs(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper, CmorderDto.class);
    }

    @Override
    public Cmorders getByOrderCode(String storeUid, String memberUid, String orderCode) {
        QueryCondition condition = table.orderCode.eq(orderCode);
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(memberUid))
            condition.and(table.memberUid.eq(memberUid));
        return getMapper().selectOneByCondition(condition);
    }

    @Override
    public CmorderDto getDtoByOrderCode(String storeUid, String memberUid, String orderCode) {
        QueryCondition condition = table.orderCode.eq(orderCode);
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(memberUid))
            condition.and(table.memberUid.eq(memberUid));
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.allColumns, members.memberName.as("newMemberName"))
                .from(table)
                .where(condition)
                .leftJoin(members).on(table.memberUid.eq(members.uid));
        return getMapper().selectOneByQueryAs(wrapper, CmorderDto.class);
    }

    @Override
    public int dropBean(String storeUid, String memberUid, String orderCode) {
        QueryCondition condition = table.storeUid.eq(storeUid)
                .and(table.memberUid.eq(memberUid))
                .and(table.orderCode.eq(orderCode));
        return getMapper().deleteByCondition(condition);
    }

    @Override
    public boolean updateStatus(String orderCode, Integer status, String statusName) {
        return UpdateChain.of(Cmorders.class)
                .set(table.status, status)
                .set(table.statusName, statusName)
                .where(table.orderCode.eq(orderCode))
                .update();
    }

    @Override
    public boolean updateStatus(String orderCode, Integer status, String statusName, String staffUid, String staffName, String remark) {
        return UpdateChain.of(Cmorders.class)
                .set(table.status, status)
                .set(table.statusName, statusName)
                .where(table.orderCode.eq(orderCode))
                .update();
    }


    @Override
    public boolean updateOrderStateAndChangeDate(String orderCode, String staffUid, String staffName, Integer orderState, String orderStateName, Date changeDate) {
        return UpdateChain.of(Cmorders.class)
                .set(table.orderState, orderState)
                .set(table.orderStateName, orderStateName)
                .set(table.changeDate, changeDate)
                .set(table.lastStaffUid, NepUtil.nullToZero(staffUid))
                .set(table.lastStaffName, NepUtil.nullToZero(staffName))
                .where(table.orderCode.eq(orderCode))
                .update();
    }

    @Override
    public long getMemberNewOrderNum(String storeUid, String memberUid) {
        QueryCondition condition = table.storeUid.eq(storeUid)
                .and(table.memberUid.eq(memberUid))
                .and(table.orderType.ne(EnumType.OrderType.EXP.getType()))
                .and(table.orderType.ne(EnumType.OrderType.GIFT.getType()));

        return getMapper().selectCountByCondition(condition);
    }

    @Override
    public List<CmorderDto> listByOrderCodeInd(List<String> orderCodeList) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.allColumns, members.memberName.as("newMemberName"))
                .from(table)
                .leftJoin(members).on(table.memberUid.eq(members.uid))
                .where(table.orderCode.in(orderCodeList))
                .orderBy(table.storeUid.asc(), table.memberUid.asc());
        return getMapper().selectListByQueryAs(wrapper, CmorderDto.class);
    }

    @Override
    public List<Cmorders> exportList(String storeUid, String keyword, String orderType, Integer status, String beginDate, String endDate) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(keyword))
            condition.and(table.contractCode.like(keyword)
                    .or(table.memberName.like(keyword))
                    .or(table.orderCode.like(keyword))
            );
        if (StringUtils.isNotBlank(orderType))
            condition.and(table.orderType.eq(orderType));
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate))
            condition.and(table.orderDate.between(beginDate, endDate));
        if (null != status)
            condition.and(table.status.eq(status));

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.orderDate.desc(), table.id.desc());

        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public List<CmorderDto> listByOrderCodeAndRelationCode(String storeUid, String orderCode, String relationCode) {
        QueryCondition condition = table.storeUid.eq(storeUid);
        if (StringUtils.isNotBlank(relationCode))
            condition.and(table.orderCode.eq(relationCode).or(table.relationCode.eq(orderCode)));
        else
            condition.and(table.relationCode.eq(orderCode));
        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.id.desc());
        return getMapper().selectListByQueryAs(wrapper, CmorderDto.class);
    }

    @Override
    public void unbindReceipt(String storeUid, String orderCode, String receiptUid) {
        QueryCondition condition = table.orderCode.eq(orderCode)
                .and(table.storeUid.eq(storeUid))
                .and(table.receiptUid.eq(receiptUid));
        UpdateChain.of(Cmorders.class)
                .set(table.receiptUid, "")
                .where(condition)
                .update();
    }

//    @Override
//    public List<String> orderCodeListBy250699(String storeUid, String memberUid) {
//        QueryCondition condition = table.storeUid.eq(storeUid)
//                .and(table.memberUid.eq(memberUid))
//                .and(table.orderAmount.eq(99))
//                .and(table.orderDate.likeLeft("2025-06"))
//                .and(table.source.eq("25年6月地推"));
//        QueryWrapper wrapper = QueryWrapper.create()
//                .select(table.orderCode)
//                .from(table)
//                .where(condition);
//        return getMapper().selectObjectListByQueryAs(wrapper, String.class);
//    }

    @Override
    public List<Cmorders> listByMemberUidInAndOrderDate(List<String> memberUidList, String ltOrderDate) {
        return getMapper().selectListByCondition(table.memberUid.in(memberUidList).and(table.orderDate.lt(ltOrderDate)));
    }

    @Override
    public List<CmOrderCountDto> listByOrderDateBetween(String storeUid, String beginDate, String endDate) {
        QueryCondition condition = table.storeUid.eq(storeUid)
                .and(table.orderDate.between(beginDate, endDate))
                .and(table.orderState.in(EnumType.CmOrderState.OK.getState()));
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.orderCode, table.orderType, table.memberUid, table.orderAmount)
                .from(table)
                .where(condition);
        return getMapper().selectListByQueryAs(wrapper, CmOrderCountDto.class);
    }

}
